/** @file generator.hpp
 *
 * @copyright (C) 2016
 * @date 2016.03.06
 * @version 1.0.0
 * @author amir zamani <azadkuh@live.com>
 *
 */

#ifndef TESTS_GENERATOR_HPP
#define TESTS_GENERATOR_HPP

#include "mbedcrypto/types.hpp"
///////////////////////////////////////////////////////////////////////////////
namespace mbedcrypto {
namespace test {
///////////////////////////////////////////////////////////////////////////////

// following functions return some sample data for various test units.

const char* short_text();
const char* long_text();

buffer_t short_binary();
buffer_t long_binary();

/// a sample RSA, 2048bit key in pem format
/// generated by:
/// @code
/// $> openssl genrsa -out mprivate.pem 2048
/// @endcode
buffer_t rsa_private_key();

/// same as above key, encrypted by AES256. password is: mbedcrypto1234
/// generated by:
/// @code
/// $> openssl rsa -aes256 -in mprivate.pem -out mprivate_encrypted.pem
/// @endcode
buffer_t rsa_private_key_password();

/// the public pair of the above key
/// generated by:
/// @code
/// $> openssl rsa -in mprivate.pem -pubout -out mpublic.pem
/// @endcode
buffer_t rsa_public_key();

/// with the above private key and long text
/// $> openssl dgst -sha1 -sign private.pem -out signature.bin long.txt
/// verification:
/// $> openssl dgst -sha1 -verify public.pem -signature signature.bin long.txt
buffer_t long_text_signature();

///////////////////////////////////////////////////////////////////////////////

/// utility function for reading a buffer in chunks
/// used by test units to test start()/update().../finish() sequences.
template <class BufferT, class Func, class... Args>
void
chunker(size_t chunk_size, const BufferT& src, Func&& func, Args&&... args) {

    const auto* data = reinterpret_cast<const uint8_t*>(src.data());

    for (size_t i = 0; (i + chunk_size) <= src.size(); i += chunk_size) {
        func(data + i, chunk_size, std::forward<Args&&>(args)...);
    }

    size_t residue = src.size() % chunk_size;
    if (residue) {
        func(
            data + src.size() - residue,
            residue,
            std::forward<Args&&>(args)...);
    }
}

/// dumps content of data as binary to filename
void dump_to_file(const buffer_t& data, const char* filename);
///////////////////////////////////////////////////////////////////////////////
inline bool
icompare(const char* a, const char* b) {
    return std::strncmp(a, b, std::strlen(b)) == 0;
}
///////////////////////////////////////////////////////////////////////////////
} // namespace test
///////////////////////////////////////////////////////////////////////////////
#if defined(QT_CORE_LIB)
inline bool operator==(const QByteArray& ba, const std::string& ss) {
    if ((size_t)ba.size() != ss.size())
        return false;
    return std::memcmp(ba.data(), ss.data(), ss.size()) == 0;
}
#endif // QT_CORE_LIB
///////////////////////////////////////////////////////////////////////////////
} // namespace mbedcrypto
///////////////////////////////////////////////////////////////////////////////
#endif // TESTS_GENERATOR_HPP
